package com.lai.hospital.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lai.hospital.dao.DoctorDao;
import com.lai.hospital.dao.DoctorScheduleDao;
import com.lai.hospital.dto.DoctorBackDTO;
import com.lai.hospital.dto.DoctorScheduleDTO;
import com.lai.hospital.dto.DoctorSchedulePreviewDTO;
import com.lai.hospital.dto.WeeklyScheduleDTO;
import com.lai.hospital.entity.Doctor;
import com.lai.hospital.entity.DoctorSchedule;
import com.lai.hospital.service.DoctorScheduleService;
import com.lai.hospital.utils.BeanCopyUtils;
import com.lai.hospital.utils.PageUtils;
import com.lai.hospital.vo.ConditionVO;
import com.lai.hospital.vo.DoctorSchedulePreviewVO;
import com.lai.hospital.vo.DoctorScheduleVO;
import com.lai.hospital.vo.PageResult;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.lai.hospital.constant.CommonConst.FALSE;
import static com.lai.hospital.constant.CommonConst.TRUE;

/**
 * @author : lai
 * @version V1.0
 * @Project: hospital-springboot
 * @Package com.lai.hospital.service.impl
 * @Description: 医生排班服务
 * @date Date : 2023年02月16日 23:48
 */
@Service
public class DoctorScheduleServiceImpl extends ServiceImpl<DoctorScheduleDao,DoctorSchedule> implements DoctorScheduleService {
    @Autowired
    private DoctorScheduleDao doctorScheduleDao;

    @Autowired
    private DoctorDao doctorDao;


    @Override
    public PageResult<DoctorBackDTO> listDoctorScheduleWeek(ConditionVO conditionVO) {
        String startTime;
        String endTime;
        Integer count;
        if(conditionVO.getStatus() == 0){//上周开始结束时间
            startTime = DateUtil.format(DateUtil.beginOfWeek(DateUtil.lastWeek()),"yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfWeek(DateUtil.lastWeek()),"yyyy-MM-dd");
        }else if(conditionVO.getStatus() == 1){//本周开始结束时间
            startTime = DateUtil.format(DateUtil.beginOfWeek(DateUtil.date()),"yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfWeek(DateUtil.date()),"yyyy-MM-dd");
        }else{//下周开始结束时间
            startTime = DateUtil.format(DateUtil.beginOfWeek(DateUtil.nextWeek()),"yyyy-MM-dd");
            endTime = DateUtil.format(DateUtil.endOfWeek(DateUtil.nextWeek()),"yyyy-MM-dd");
        }
        //查询出全部医生
        List<DoctorBackDTO> doctorBackDTOS = doctorDao.listDoctorSchedule(PageUtils.getLimitCurrent(), PageUtils.getSize(), conditionVO);
        //获取他们的id
        List<Integer> idList = doctorBackDTOS.stream().map(DoctorBackDTO::getId).collect(Collectors.toList());
        //获取指定 周  的医生排班信息
        List<DoctorScheduleDTO> doctorScheduleDTOList = doctorScheduleDao.listDoctorScheduleWeek(PageUtils.getLimitCurrent(), PageUtils.getSize(), conditionVO,startTime,endTime,idList);

        //把这周的相同的医生的排班收集一条信息 （去重）
        List<DoctorScheduleDTO> doctorScheduleDTOListByDoctorId = doctorScheduleDTOList.stream().collect(Collectors.collectingAndThen
                        (Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing
                                (DoctorScheduleDTO::getDoctorId))), ArrayList::new));
        //遍历全部的医生排班  把  排班的信息放入ArrayList<WeeklyScheduleDTO>中
        for (DoctorScheduleDTO doctorScheduleDTO : doctorScheduleDTOListByDoctorId) {
            ArrayList<WeeklyScheduleDTO> weeklyScheduleDTOS = new ArrayList<>();
            doctorScheduleDTO.setWeeklySchedule(weeklyScheduleDTOS);

            for (DoctorScheduleDTO scheduleDTO : doctorScheduleDTOList) {
                if (scheduleDTO.getDoctorId() == doctorScheduleDTO.getDoctorId()) {
                    //构建参数
                    WeeklyScheduleDTO weeklyScheduleDTO = WeeklyScheduleDTO.builder()
                            .weekDay(DateUtil.dayOfWeekEnum(scheduleDTO.getScheduleTime()).toChinese())
                            .timeQuantum(scheduleDTO.getTimeQuantum())
                            .numberSource(scheduleDTO.getNumberSource())
                            .build();
                    //添加进集合中 ArrayList<WeeklyScheduleDTO>
                    weeklyScheduleDTOS.add(weeklyScheduleDTO);
                }
            }
        }
        //遍历获取 设置指定医生的排班
        for (DoctorBackDTO doctorBackDTO : doctorBackDTOS) {
            for (DoctorScheduleDTO doctorScheduleDTO : doctorScheduleDTOListByDoctorId) {
                if(doctorBackDTO.getId() == doctorScheduleDTO.getDoctorId()){
                    doctorBackDTO.setDoctorScheduleDTO(doctorScheduleDTO);
                }
            }
        }
        //设置列表总数   有条件查询时doctorDTOList的大小
        if (StringUtils.isNotBlank(conditionVO.getKeywords()) || Objects.nonNull(conditionVO.getDepartmentId())) {
            count = doctorBackDTOS.size();
        } else {//无条件查询时获取全部数据
            count = doctorDao.selectCount(null);
        }

        return new PageResult<>(doctorBackDTOS, count);
    }

    @Override
    public void saveDoctorSchedule(DoctorScheduleVO doctorScheduleVO) {
        if(doctorScheduleVO.getAmTimeQuantum()){//上午接诊
            DoctorSchedule doctorSchedule = DoctorSchedule.builder()
                    .doctorId(doctorScheduleVO.getDoctorId())
                    .departmentId(doctorScheduleVO.getDepartmentId())
                    .scheduleTime(doctorScheduleVO.getScheduleTime())
                    .timeQuantum(FALSE)
                    .numberSource(doctorScheduleVO.getAmNumberSource())
                    .build();
            doctorScheduleDao.insert(doctorSchedule);
        }
        if(doctorScheduleVO.getPmTimeQuantum()){//下午接诊
            DoctorSchedule doctorSchedule = DoctorSchedule.builder()
                    .doctorId(doctorScheduleVO.getDoctorId())
                    .departmentId(doctorScheduleVO.getDepartmentId())
                    .scheduleTime(doctorScheduleVO.getScheduleTime())
                    .timeQuantum(TRUE)
                    .numberSource(doctorScheduleVO.getPmNumberSource())
                    .build();
            doctorScheduleDao.insert(doctorSchedule);
        }
    }

    @Override
    public List<DoctorSchedulePreviewDTO> getDoctorScheduleByDoctorIdAndTime(DoctorSchedulePreviewVO doctorSchedulePreviewVO) {
        if(StringUtils.isBlank(doctorSchedulePreviewVO.getAppointmentTime()) || Objects.isNull(doctorSchedulePreviewVO.getAppointmentTime())
                || "null".equals(doctorSchedulePreviewVO.getAppointmentTime())){
            doctorSchedulePreviewVO.setAppointmentTime(DateUtil.format(DateUtil.date(), "yyyy-MM-dd"));
        }
        //转换成DoctorSchedulePreviewDTO
            List<DoctorSchedule> doctorSchedules = doctorScheduleDao.selectList(new LambdaQueryWrapper<DoctorSchedule>()
                    .eq(DoctorSchedule::getDoctorId, doctorSchedulePreviewVO.getDoctorId())
                    .eq(DoctorSchedule::getScheduleTime,doctorSchedulePreviewVO.getAppointmentTime()));
            List<DoctorSchedulePreviewDTO> doctorScheduleDTOList = BeanCopyUtils.copyList(doctorSchedules, DoctorSchedulePreviewDTO.class);
            return doctorScheduleDTOList.stream().map(item -> {
                item.setMonthDay(DateUtil.today().split("-")[1] + "月" + DateUtil.today().split("-")[2] + "号");
                item.setWeek(DateUtil.dayOfWeekEnum(item.getScheduleTime()).toChinese());

                return item;
            }).collect(Collectors.toList());

    }
}
